package org.linlinjava.litemall.wx.web;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.PageInfo;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.TradeStatus.WxTradeStatus;
import org.linlinjava.litemall.core.config.DesNoViUtil;
import org.linlinjava.litemall.core.notify.NotifyService;
import org.linlinjava.litemall.core.notify.NotifyType;
import org.linlinjava.litemall.core.systemConfig.SystemConfig;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ParseXmlUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.service.CaptchaCodeManager;
import org.linlinjava.litemall.wx.util.IpUtil;
import org.linlinjava.litemall.wx.util.WxPlaceOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

@RestController
@RequestMapping("/wx/wallet")
public class WxWalletController {

	private final Log logger = LogFactory.getLog(WxWalletController.class);

	//超时循环次数
	int num = 0;

	@Autowired
	private PlatformTransactionManager txManager;

	@Autowired
	private WxPayService wxPayService;

	@Autowired
	private NotifyService notifyService;

	@Autowired
	private LitemallConfigService configService;

	@Autowired
	private LitemallUserService userService;

	@Autowired
	private LitemallWalletRecordService walletRecordService;

	@Autowired
	private LitemallMechanismService mechanismService;

	@Autowired
	private LitemallMechanismUserService mechanismUserService;

	@RequestMapping("list")//爱币和积分的值
	public Object list(@LoginUser Integer userId) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		//获取用户积分和爱币数量
		Map<String, Object> result = new HashMap<>();
		LitemallUser user = userService.findById(userId);
		if (user == null) {
			return ResponseUtil.fail();
		}
		result.put("integral", user.getIntegral());
		result.put("balance", user.getBalance());
		result.put("mobile", user.getMobile());
		return ResponseUtil.ok(result);
	}

	@RequestMapping("detailList")//明细列表
	public Object detailList(
		@LoginUser Integer userId, @RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "limit", defaultValue = "10") Integer limit, String sort, String order) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}

		List<LitemallWalletRecord> walletRecords = walletRecordService.querySelectiveByUserId(userId, page, limit, sort, order);
		long totalPages = PageInfo.of(walletRecords).getTotal();
		Map<String, Object> data = new HashMap<>(4);
		data.put("total", totalPages);
		data.put("walletRecords", walletRecords);

		return ResponseUtil.ok(data);
	}

	@RequestMapping("detail")//查看单个记录的详情信息
	public Object detail(@LoginUser Integer userId, Integer orderId) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}

		LitemallWalletRecord litemallWalletRecord = walletRecordService.queryById(orderId);
		Map<String, Object> data = new HashMap<>();
		data.put("walletInfo", litemallWalletRecord);

		return ResponseUtil.ok(data);
	}

	@RequestMapping("update")//修改支付密码
	public Object updateUserPayPassword(@LoginUser Integer userId, String mobile, String code, String payPassword) {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}

		//判断验证码是否正确
		String cacheCode = CaptchaCodeManager.getCachedCaptcha(mobile);
		if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code)) {
			return ResponseUtil.fail(403, "验证码错误");
		}
		LitemallUser user = userService.findById(userId);

		String uMobile = user.getMobile();
		if (uMobile != null) {
			uMobile = uMobile.replace(" ", "");
		} else {
			uMobile = "";
		}
		if (uMobile.equals(mobile.replace(" ", ""))) {

			BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
			String encodedPayPassword = encoder.encode(payPassword);
			user.setPayPassword(encodedPayPassword);
			userService.update(user);
			return ResponseUtil.ok();
		} else {
			return ResponseUtil.fail(-1, "手机号错误");
		}

	}

	@PostMapping("regCaptcha")
	public Object registerCaptcha(@RequestBody String body) {
		String phoneNumber = JacksonUtil.parseString(body, "mobile");
		String code = CharUtil.getRandomNum(6);
		String params = new String("{\"code\":\"" + code + "\"}");

		notifyService.notifySmsTemplateSync(phoneNumber, NotifyType.CAPTCHA, params);
		try {
			Thread.sleep(5000);
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
		boolean successful = CaptchaCodeManager.addToCache(phoneNumber, code);
		return successful ? ResponseUtil.ok() : ResponseUtil.badArgument();
	}

	@RequestMapping("payWallet")//充值爱币
	public Object payWallet(
		@LoginUser Integer userId, @RequestBody String body, HttpServletRequest request) throws Exception {

		//解密
		DesNoViUtil tools = new DesNoViUtil();

		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		LitemallUser user = userService.findById(userId);
		String typeStr = JacksonUtil.parseString(body, "type");
		String modifyReasonStr = tools.decode(JacksonUtil.parseString(body, "modifyReason"));
		String recordSnStr = tools.decode(JacksonUtil.parseString(body, "recordSn"));
		String modifyAmountStr = tools.decode(JacksonUtil.parseString(body, "modifyAmount"));
		String payTypeStr = JacksonUtil.parseString(body, "payType");

		LitemallWalletRecord walletRecord = new LitemallWalletRecord();
		byte type = (byte)Integer.parseInt(typeStr);
		walletRecord.setType(type);
		byte payType = (byte)Integer.parseInt(payTypeStr);
		walletRecord.setPayType(payType);
		walletRecord.setModifyReason(modifyReasonStr);
		walletRecord.setRecordSn(recordSnStr);
		BigDecimal modifyAmount = new BigDecimal(Integer.parseInt(modifyAmountStr));
		walletRecord.setModifyAmount(modifyAmount);
		walletRecord.setModifyIntegral(0);

		walletRecord.setUserId(userId);
		String openid = user.getWeixinOpenid();
		if (openid == null) {
			return ResponseUtil.fail(-1, "订单不能支付");
		}

		if (modifyAmount == null) {
			return ResponseUtil.fail(-1, "请填写充值金额");
		}
		if (modifyAmount.compareTo(BigDecimal.ZERO) == 0) {
			return ResponseUtil.fail(-1, "请填写充值金额");
		}
		LitemallConfig ANBToRMBConfig = configService.findById(10000001);
		Double ANBToRMBValue = Double.parseDouble(ANBToRMBConfig.getValue());
		BigDecimal rmb = new BigDecimal(ANBToRMBValue).multiply(modifyAmount).setScale(2, BigDecimal.ROUND_HALF_UP);

		if (rmb.compareTo(new BigDecimal(0.01)) < 0) {
			//不足1分按1分计算
			rmb = new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP);
		}

		// 开启事务管理
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		TransactionStatus status = txManager.getTransaction(def);
		WxPayMpOrderResult result = null;

		try {
			WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
			orderRequest.setOutTradeNo(recordSnStr);
			orderRequest.setOpenid(openid);
			orderRequest.setBody("订单：" + recordSnStr);
			// 元转成分
			Integer fee = 0;
			fee = rmb.multiply(new BigDecimal(100)).intValue();
			orderRequest.setTotalFee(fee);
			orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request));

			result = wxPayService.createOrder(orderRequest);
			walletRecord.setActualPayment(rmb);
			walletRecord.setModifyReason("爱币充值(本人)");
			walletRecord.setModifyTime(LocalDateTime.now());
			walletRecordService.add(walletRecord);
			Integer walletRecordId = walletRecord.getId();
			if (walletRecordId == null || walletRecordId.equals("")) {
				return ResponseUtil.fail(-1, "支付失败");
			}
		}
		catch (Exception ex) {
			txManager.rollback(status);
			logger.error("支付失败！", ex);
			ex.printStackTrace();
			return ResponseUtil.fail(-1, "支付失败");
		}
		txManager.commit(status);
		return ResponseUtil.ok(result);
	}

	/**
	 * 充值会员
	 *
	 * @param userId
	 * @param body
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("payWalletMember")
	public Object payWalletMember(
		@LoginUser Integer userId, @RequestBody String body, HttpServletRequest request) throws Exception {
		//解密
		DesNoViUtil tools = new DesNoViUtil();
		if (userId == null) {
			return ResponseUtil.unlogin();
		}
		LitemallUser user = userService.findById(userId);
		BigDecimal balance = user.getBalance();
		String payPassword = tools.decode(JacksonUtil.parseString(body, "payPassword"));
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		if (payPassword != null && !encoder.matches(payPassword, user.getPayPassword())) {
			return ResponseUtil.fail(-3, "支付密码不对");
		}
		String openid = user.getWeixinOpenid();
		if (openid == null) {
			return ResponseUtil.fail(-1, "订单不能支付");
		}
		if (balance.intValue() < 66) {
			return ResponseUtil.fail(-2, "您的余额不足,请去钱包充值爱币");
		}
		//用户所在机构
		LitemallMechanism mechanism = null;
		//机构的使用者
		LitemallMechanismUser litemallMechanismUser = null;
		if (!StringUtils.isEmpty(user.getFirstMechanism())) {
			mechanism = mechanismService.findById(user.getFirstMechanism());
            if(mechanism.getNewProxyFlag()){
            	user.setNewProxyFlag(true);
            }
			litemallMechanismUser = mechanismUserService.findUserByMid(mechanism.getId());
		} else {
			//推荐码
			String referCode = tools.decode(JacksonUtil.parseString(body, "referCode"));
			if (!StringUtils.isEmpty(referCode)) {
				referCode.toUpperCase();
				//通过邀请码查找用户机构
				LitemallMechanism litemallMechanism = mechanismService.findByReferCode(referCode);
				if (litemallMechanism != null) {
					litemallMechanismUser = mechanismUserService.findUserByMid(litemallMechanism.getId());
					mechanism = litemallMechanism;
					user.setFirstMechanism(litemallMechanism.getId());
				} else {
					return ResponseUtil.fail(-1, "推荐码不正确");
				}
			}
		}
		String typeStrMechanism = JacksonUtil.parseString(body, "type");
		String modifyReasonStr = tools.decode(JacksonUtil.parseString(body, "modifyReason"));
		String recordSnStr = tools.decode(JacksonUtil.parseString(body, "recordSn"));
		String payTypeStr = JacksonUtil.parseString(body, "payType");

		//用户钱包
		LitemallWalletRecord walletRecord = new LitemallWalletRecord();
		//机构人员钱包
		LitemallWalletRecord walletRecordMechanism = new LitemallWalletRecord();
		//爱能钱包
		LitemallWalletRecord litemallWalletRecord16 = new LitemallWalletRecord();

		byte typeMechanism = (byte)Integer.parseInt(typeStrMechanism);
		byte payType = (byte)Integer.parseInt(payTypeStr);
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
		String newsNo = LocalDateTime.now().format(fmt);
		walletRecordMechanism.setType(typeMechanism);
		walletRecordMechanism.setModifyTime(LocalDateTime.now());
		walletRecord.setType((byte)2);
		walletRecord.setPayType(payType);
		walletRecord.setModifyReason(modifyReasonStr);
		walletRecord.setRecordSn(recordSnStr);
		walletRecord.setModifyIntegral(0);
		walletRecord.setUserId(userId);
		walletRecord.setModifyReason("充值会员");
		walletRecord.setPayId(newsNo);
		walletRecord.setPayTime(LocalDateTime.now());
		walletRecord.setModifyTime(LocalDateTime.now());

		BigDecimal modifyAmount = new BigDecimal(SystemConfig.getMemberCharge());
		BigDecimal modifyAmountMechanism = new BigDecimal(50);
		BigDecimal modifyAmountMechanismSix = new BigDecimal(66);
		BigDecimal aiLianModifyAmount;
		BigDecimal bd = new BigDecimal(SystemConfig.getMemberCharge());
		walletRecord.setModifyAmount(bd.multiply(new BigDecimal(-1)));

		//有首绑机构并且机构等级不是1
		if (mechanism != null) {
			if (mechanism.getLevel() == null || mechanism.getLevel() > (byte)1) {
				//给机构用户返50
				walletRecordMechanism.setModifyReason("用户充值会员,返还给机构");
				walletRecordMechanism.setMechaismId(litemallMechanismUser.getId());
				walletRecordMechanism.setType(new Byte("5"));
				walletRecordMechanism.setModifyTime(LocalDateTime.now());
				walletRecordMechanism.setModifyAmount(modifyAmountMechanism);

				//16块返爱能
				litemallWalletRecord16.setModifyAmount(new BigDecimal(16));
				litemallWalletRecord16.setModifyReason("用户充值会员，返回给爱能");
				litemallWalletRecord16.setModifyTime(LocalDateTime.now());
				litemallWalletRecord16.setType(new Byte("5"));
				litemallWalletRecord16.setMechaismId(SystemConfig.getAiLianNum());
				aiLianModifyAmount = new BigDecimal(16);
				walletRecordService.add(litemallWalletRecord16);
			} else {
				// 66全返给爱能
				walletRecordMechanism.setModifyReason("用户充值会员,返还给爱能");
				walletRecordMechanism.setModifyTime(LocalDateTime.now());
				walletRecordMechanism.setType(new Byte("5"));
				walletRecordMechanism.setMechaismId(SystemConfig.getAiLianNum());
				walletRecordMechanism.setModifyAmount(modifyAmountMechanismSix);
				aiLianModifyAmount = new BigDecimal(66);
			}

		} else {
			// 66全返给爱能
			walletRecordMechanism.setModifyReason("用户充值会员,返还给爱能");
			walletRecordMechanism.setModifyTime(LocalDateTime.now());
			walletRecordMechanism.setType(new Byte("5"));
			aiLianModifyAmount = new BigDecimal(66);
			walletRecordMechanism.setMechaismId(SystemConfig.getAiLianNum());
			walletRecordMechanism.setModifyAmount(modifyAmountMechanismSix);
		}
		//添加用户消费记录
		walletRecordService.add(walletRecord);
		//添加机构消费记录
		walletRecordService.add(walletRecordMechanism);

		if (user.getMemberType() == null) {
			user.setMemberType(false);
		}
        // 用户扣除爱币
		if (!user.getMemberType()) {
			if (user.getMemberEndtime() != null) {
				user.setMemberEndtime(user.getMemberEndtime().plusYears(1));
			} else {
				user.setMemberEndtime(LocalDateTime.now().plusYears(1));
			}
			user.setBalance(balance.subtract(modifyAmount));
			user.setMemberType(true);
			userService.update(user);

			//爱联账户增加返币
			LitemallMechanismUser aiLianMechanismUser = mechanismUserService.findById(SystemConfig.getAiLianNum());
			if (aiLianMechanismUser.getBalance() == null) {
				aiLianMechanismUser.setBalance(aiLianModifyAmount);
			} else {
				aiLianMechanismUser.setBalance(aiLianMechanismUser.getBalance().add(aiLianModifyAmount));
			}
			mechanismUserService.update(aiLianMechanismUser);
			//机构用户增加返币
			if (mechanism != null) {
				if (litemallMechanismUser.getBalance() == null) {
					mechanismUserService.updateBalance(modifyAmountMechanism, mechanism.getId());
				} else {
					mechanismUserService.updateBalanceByMechanismId(modifyAmountMechanism, mechanism.getId());
				}
			}
		}
		Integer walletRecordId = walletRecord.getId();
		if (walletRecordId == null || "".equals(walletRecordId)) {
			return ResponseUtil.fail(-1, "支付失败");
		}
		return ResponseUtil.ok("success");
	}

	@GetMapping("/checkchargestatus")
	public Object checkChargeStatus(@LoginUser Integer userId, String recordSn) {

		Map<String, Object> data = new HashMap<>();

		ExecutorService executorService = Executors.newSingleThreadExecutor();
		FutureTask<String> future = new FutureTask<>(() -> {
			LitemallWalletRecord walletRecord = walletRecordService.queryByRecordSn(recordSn);
			if (walletRecord == null) {
				data.put("orderStatus", "FAIL");
			}
			if (walletRecord.getPayId() == null || walletRecord.getPayId().equals("")) {
				try {
					WxPayOrderQueryResult orderQueryResult = wxPayService.queryOrder("", recordSn);
					String returnCode = orderQueryResult.getReturnCode();
					String resultCode = orderQueryResult.getResultCode();
					String tradeState = orderQueryResult.getTradeState();
					if (returnCode.equals(WxTradeStatus.SUCCESS) && resultCode.equals(WxTradeStatus.SUCCESS) && tradeState.equals(WxTradeStatus.SUCCESS)) {
						data.put("orderStatus", "SUCCESS");
					} else {
						data.put("orderStatus", "FAIL");
					}
				}
				catch (Exception e) {
					logger.error("微信回调结果异常,异常原因 " + e.getMessage());
					return WxPayNotifyResponse.fail(e.getMessage());
				}
			} else {
				data.put("orderStatus", "SUCCESS");
			}
			return "success";
		});
		executorService.execute(future);

		try {
			String result = future.get(1, TimeUnit.SECONDS);
			logger.info("result:" + result);
		}
		catch (TimeoutException e) {
			num += 1;
			if (num < 4) {
				System.out.println("超时了!");
				this.checkChargeStatus(userId, recordSn);
			} else {
				System.out.println("联系管理员!");
			}
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
		catch (ExecutionException e) {
			e.printStackTrace();
		}

		return ResponseUtil.ok(data);
	}

	@GetMapping("/exchangeintegral")
	public Object exchangeIntegral(@LoginUser Integer userId, String password, String recordSn, String modifyIntegral) throws Exception {
		if (userId == null) {
			return ResponseUtil.unlogin();
		}

		DesNoViUtil tools = new DesNoViUtil();
		String recordSnStr = tools.decode(recordSn);
		String modifyIntegralStr = tools.decode(modifyIntegral);
		Integer modifyIntegralInt = Integer.parseInt(modifyIntegralStr);

		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		TransactionStatus status = txManager.getTransaction(def);
		LitemallWalletRecord walletRecord = new LitemallWalletRecord();

		LitemallUser user = userService.findById(userId);

		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

		if (!StringUtils.isEmpty(password) && encoder.matches(password, user.getPayPassword())) {
			try {
				LitemallConfig integralToANBConfig = configService.findById(10000003);
				Double integralToANBValue = Double.parseDouble(integralToANBConfig.getValue());

				//兑换的爱币数量
				//                BigDecimal ANB = new BigDecimal(modifyAmount);
				//                walletRecord.setModifyAmount(ANB.multiply(new BigDecimal(-1)));

				//兑换的积分数量
				walletRecord.setModifyIntegral(modifyIntegralInt);
				//要扣除的爱币数量
				BigDecimal modifyAmount = new BigDecimal(modifyIntegralInt * integralToANBValue);
				walletRecord.setModifyAmount(modifyAmount.multiply(new BigDecimal(-1)));

				//用户的爱币兑换积分  可以兑换到的积分
				//                Integer anbToIntegral = ANB.divide(new BigDecimal(integralToANBValue)).intValue();
				//                walletRecord.setModifyIntegral(anbToIntegral);
				walletRecord.setModifyReason("用户爱币兑换积分");
				walletRecord.setUserId(userId);
				walletRecord.setModifyTime(LocalDateTime.now());
				walletRecord.setPayTime(LocalDateTime.now());
				walletRecord.setType(new Byte("3"));
				walletRecord.setPayType(new Byte("3"));
				walletRecord.setPayId(recordSnStr);
				walletRecord.setRecordSn(recordSnStr);

				//爱币数量不足，不能兑换 前台限制
				if (user.getBalance().compareTo(modifyAmount) < 0) {
					Map<String, Object> obj = new HashMap<String, Object>();
					obj.put("errno", -1);
					obj.put("errmsg", "爱币不足");
					return obj;

				} else {
					user.setBalance(user.getBalance().subtract(modifyAmount));
					user.setIntegral(user.getIntegral() + modifyIntegralInt);
					userService.update(user);
					walletRecordService.add(walletRecord);

				}

			}
			catch (Exception ex) {
				txManager.rollback(status);
				logger.error("兑换错误！", ex);
			}
			txManager.commit(status);

			return ResponseUtil.ok();
		} else {
			txManager.rollback(status);

			Map<String, Object> obj = new HashMap<>(2);
			obj.put("errno", -1);
			obj.put("errmsg", "支付密码错误");
			return obj;
		}

	}

	/**
	 * 充值爱币付款成功回调接口
	 * 1. 检测当前订单是否是付款状态
	 * 2. 设置订单付款成功状态相关信息
	 * 3. 响应微信支付平台
	 * * @return 订单操作结果
	 * 成功则 WxPayNotifyResponse.success的XML内容
	 * 失败则 WxPayNotifyResponse.fail的XML内容
	 * <p>
	 * 注意，这里pay-notify是示例地址，开发者应该设立一个隐蔽的回调地址
	 */
	@PostMapping("/voucherReturn")
	public void payNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("有请求过阿莱了");
		Map<String, String> map = ParseXmlUtil.parseXml(request);
		WxPlaceOrder wxPlaceOrder = new WxPlaceOrder();
		String   trade_status =    map.get("return_code");
		String out_trade_no ;
		if(trade_status.equals(WxTradeStatus.SUCCESS)){
			if(map.get("result_code").equals(WxTradeStatus.SUCCESS)){
				out_trade_no =   map.get("out_trade_no");
				logger.info("out_trade_no:"+out_trade_no);
				String trade_no =   map.get("transaction_id");
				logger.info("trade_no:"+trade_no);
				LitemallWalletRecord litemallWalletRecord = walletRecordService.queryByRecordSn(out_trade_no);
				if(litemallWalletRecord != null){
					if(litemallWalletRecord.getPayId() == null){
						litemallWalletRecord.setPayId(trade_no);
						litemallWalletRecord.setPayTime(LocalDateTime.now());
						walletRecordService.update(litemallWalletRecord);

						if(litemallWalletRecord.getType() == 1){
							LitemallUser user = userService.findById(litemallWalletRecord.getUserId());
							BigDecimal lastPrice = user.getBalance().add(litemallWalletRecord.getModifyAmount());
							user.setBalance(lastPrice);
							userService.update(user);

							Date dd=new Date();
							SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							String time=sim.format(dd);
							String[] params = new String[] {"爱币", litemallWalletRecord.getActualPayment()+"" , time};
							notifyService.notifyWxTemplate(user.getWeixinOpenid(), NotifyType.RECHARGESUCCESS, params);
						}
					}
				}
			}
			// 通知成功
			wxPlaceOrder.setReturn_code("SUCCESS");
			XStream xStream = new XStream(new StaxDriver(new NoNameCoder()));
			xStream.alias("xml", WxPlaceOrder.class);
			String returnXml = xStream.toXML(wxPlaceOrder);
			try {
				response.getWriter().write(returnXml);
			} catch (IOException e) {
				System.out.println("通知回调 微信服务器 异常:"+ e);
			}
		}
	}


	/**
	 * <pre>
	 * 微信支付-申请退款
	 * 说明：因退款操作存在结果延时，需要等待微信通知结果
	 * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
	 * 接口链接：https://api.mch.weixin.qq.com/secapi/pay/refund
	 * </pre>
	 *
	 * @return 退款操作结果
	 */

	@PostMapping("/refund")
	public Object refund(WxPayOrderNotifyResult wxPayOrderNotifyResult) {

		String oper = "weixin_refund";

		LitemallWalletRecord walletRecord = walletRecordService.queryByRecordSn(wxPayOrderNotifyResult.getOutTradeNo());
		if (walletRecord == null) {

			return ResponseUtil.fail(-1, "支付失败");
		}

		WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
		wxPayRefundRequest.setOutTradeNo(wxPayOrderNotifyResult.getOutTradeNo());

		wxPayRefundRequest.setOutRefundNo(wxPayOrderNotifyResult.getOutTradeNo());
		BigDecimal totalFeeBd = null;
		Integer totalFeeInt = 0;
		BigDecimal refundFeeBd = null;
		Integer refundFeeInt = 0;
		try {
			totalFeeBd = new BigDecimal(wxPayOrderNotifyResult.getTotalFee()).setScale(2, BigDecimal.ROUND_HALF_UP);
			totalFeeInt = totalFeeBd.multiply(new BigDecimal(100)).intValue();
		}
		catch (Exception e) {

		}

		wxPayRefundRequest.setTotalFee(totalFeeInt);
		wxPayRefundRequest.setRefundFee(totalFeeInt);
		//退款结果通知url
		String notify_url = "";
		wxPayRefundRequest.setNotifyUrl(notify_url);
		try {
			WxPayRefundResult refundResult = wxPayService.refund(wxPayRefundRequest);
			String returnCode = refundResult.getReturnCode();
			String resultCode = refundResult.getResultCode();
			// 处理微信返回结果
			if ("SUCCESS".equals(returnCode)) {
				if ("SUCCESS".equals(resultCode)) {
					// 将退款记录保存到数据库
				} else {
					return ResponseUtil.fail(-1, "退款失败");
				}
			} else {
				return ResponseUtil.fail(-1, "退款失败");
			}
		}
		catch (WxPayException e) {
			return ResponseUtil.fail(-1, "退款失败");
		}
		catch (Exception e) {
			return ResponseUtil.fail(-1, e.getMessage());
		}
		return ResponseUtil.fail(-1, "微信退款中");
	}

}

